using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using MT5Trade.Models.MarketData;

namespace MT5Trade
{
    /// <summary>
    /// 文件缓存测试程序
    /// </summary>
    public class TestFileCache
    {
        public static async Task Main(string[] args)
        {
            Console.WriteLine("========================================");
            Console.WriteLine("Yahoo Finance 文件缓存测试");
            Console.WriteLine("========================================\n");

            // 创建日志
            using var loggerFactory = LoggerFactory.Create(builder =>
            {
                builder.AddConsole();
                builder.SetMinimumLevel(LogLevel.Information);
            });

            var logger = loggerFactory.CreateLogger<YahooFinanceDataProvider>();
            var cacheLogger = loggerFactory.CreateLogger<FileDataCache>();

            // 创建文件缓存和数据提供者
            var fileCache = new FileDataCache(logger: cacheLogger);
            var dataProvider = new YahooFinanceDataProvider(
                logger: logger,
                fileCache: fileCache);

            // 测试品种列表
            var testSymbols = new List<string>
            {
                "SPY",        // S&P 500 ETF
                "EURUSD=X",   // 欧元/美元
                "GC=F"        // 黄金期货
            };

            Console.WriteLine("第1步: 显示缓存统计信息");
            Console.WriteLine("----------------------------------------");
            ShowCacheStatistics(dataProvider);

            Console.WriteLine("\n第2步: 第一次下载数据（会调用API）");
            Console.WriteLine("----------------------------------------");
            Console.WriteLine("正在下载数据，请稍候...\n");

            var startTime = DateTime.Now;
            var result1 = await dataProvider.BatchDownloadAndCacheAsync(testSymbols, lookbackDays: 7);
            var duration1 = (DateTime.Now - startTime).TotalSeconds;

            Console.WriteLine($"\n下载完成！耗时: {duration1:F2} 秒");
            ShowDownloadResults(result1);

            Console.WriteLine("\n第3步: 再次获取相同数据（从文件缓存读取）");
            Console.WriteLine("----------------------------------------");
            Console.WriteLine("正在从缓存读取数据...\n");

            startTime = DateTime.Now;
            var result2 = await dataProvider.BatchDownloadAndCacheAsync(testSymbols, lookbackDays: 7);
            var duration2 = (DateTime.Now - startTime).TotalSeconds;

            Console.WriteLine($"\n读取完成！耗时: {duration2:F2} 秒");
            Console.WriteLine($"速度提升: {(duration1 / duration2):F1}x");
            ShowDownloadResults(result2);

            Console.WriteLine("\n第4步: 显示更新后的缓存统计");
            Console.WriteLine("----------------------------------------");
            ShowCacheStatistics(dataProvider);

            Console.WriteLine("\n第5步: 测试单个品种的缓存");
            Console.WriteLine("----------------------------------------");
            await TestSingleSymbolCache(dataProvider);

            Console.WriteLine("\n========================================");
            Console.WriteLine("测试完成！");
            Console.WriteLine("缓存文件位置: MarketDataCache/");
            Console.WriteLine("========================================");
        }

        private static void ShowCacheStatistics(YahooFinanceDataProvider provider)
        {
            var stats = provider.GetCacheStatistics();
            Console.WriteLine($"缓存目录: {stats.CacheDirectory}");
            Console.WriteLine($"总文件数: {stats.TotalFiles}");
            Console.WriteLine($"活跃文件: {stats.ActiveFiles}");
            Console.WriteLine($"过期文件: {stats.ExpiredFiles}");
            Console.WriteLine($"总大小: {stats.TotalSizeMB:F2} MB");
        }

        private static void ShowDownloadResults(Dictionary<string, List<MarketTick>> results)
        {
            foreach (var kvp in results)
            {
                var symbol = kvp.Key;
                var data = kvp.Value;

                if (data != null && data.Count > 0)
                {
                    var first = data[0];
                    var last = data[data.Count - 1];

                    Console.WriteLine($"\n{symbol}:");
                    Console.WriteLine($"  记录数: {data.Count}");
                    Console.WriteLine($"  时间范围: {first.Time:yyyy-MM-dd} 至 {last.Time:yyyy-MM-dd}");
                    Console.WriteLine($"  最新收盘价: {last.Close:F2}");

                    // 计算简单统计
                    decimal avgClose = 0;
                    decimal maxClose = decimal.MinValue;
                    decimal minClose = decimal.MaxValue;

                    foreach (var tick in data)
                    {
                        avgClose += tick.Close;
                        if (tick.Close > maxClose) maxClose = tick.Close;
                        if (tick.Close < minClose) minClose = tick.Close;
                    }
                    avgClose /= data.Count;

                    Console.WriteLine($"  平均价: {avgClose:F2}");
                    Console.WriteLine($"  最高价: {maxClose:F2}");
                    Console.WriteLine($"  最低价: {minClose:F2}");
                }
                else
                {
                    Console.WriteLine($"\n{symbol}: 无数据");
                }
            }
        }

        private static async Task TestSingleSymbolCache(YahooFinanceDataProvider provider)
        {
            var symbol = "AAPL";
            var endDate = DateTime.UtcNow;
            var startDate = endDate.AddDays(-5);

            Console.WriteLine($"\n测试品种: {symbol}");
            Console.WriteLine($"日期范围: {startDate:yyyy-MM-dd} 至 {endDate:yyyy-MM-dd}");

            // 第一次调用（可能从API获取）
            Console.WriteLine("\n第一次调用...");
            var start = DateTime.Now;
            var data1 = await provider.GetHistoricalDataAsync(symbol, startDate, endDate);
            var time1 = (DateTime.Now - start).TotalMilliseconds;
            Console.WriteLine($"耗时: {time1:F0} ms, 数据条数: {data1?.Count ?? 0}");

            // 第二次调用（应该从缓存获取）
            Console.WriteLine("\n第二次调用（应该从缓存）...");
            start = DateTime.Now;
            var data2 = await provider.GetHistoricalDataAsync(symbol, startDate, endDate);
            var time2 = (DateTime.Now - start).TotalMilliseconds;
            Console.WriteLine($"耗时: {time2:F0} ms, 数据条数: {data2?.Count ?? 0}");

            if (time2 < time1)
            {
                Console.WriteLine($"\n✅ 缓存生效！速度提升 {(time1/time2):F1}x");
            }
        }
    }
}